//////////////////////////////////////////////////////////////////////
////                                                              ////
////  SysGenStepClock.v                                           ////
////                                                              ////
////                                                              ////
////  This file is part of the "Pico E12" project                 ////
////  http://www.picocomputing.com                                ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2005, Picocomputing, Inc.                      ////
//// http://www.picocomputing.com/                                ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
////////////////////////////////////////////////////////////////////JF

//This module generates a synchronous and asynchronous clock for the System Generator (TM) module
//This module is optimized for speed (665 MHz on the slowest Virtex-4 speed grade)
`timescale 10ns / 1ns
`include "PicoDefines.v"


module SysGenStepClock(SysGen_pci_clk_nobuf, SysGen_pci_clk, SysGenStep, MemRead, MemWrite, MemAddress, DataIn, DataOut);

input SysGen_pci_clk_nobuf;                                                 //Free running, unbuffered system generator clock
input SysGen_pci_clk;                                                       //Free running system generator clock
output SysGenStep;                                                          //System generator step clock

input MemRead;
input MemWrite;
input [31:1]MemAddress;
input [15:0]DataIn;
output [15:0]DataOut;

wire SysGenStepClockRead;

reg [16:0]Shifty;                                                           //For each "1" that is stored in this shift register - one tick will be generated                              
//synthesis attribute INIT of Shifty is 00000000000000000

//Basic Function Decoding
assign SysGenStepClockWrite = (MemAddress[31:1] == `SYSGEN_STEP_CLOCK_ADDRESS) && (MemWrite);
assign SysGenStepClockRead = (MemAddress[31:1] == `SYSGEN_STEP_CLOCK_ADDRESS) && (MemRead);

//Retun zero if the shift register is empty, non-zero if full
assign DataOut[15:1] = (SysGenStepClockRead)?(Shifty[16:2]) : 16'b0;        //See if clock counter is empty
assign DataOut[0] = (SysGenStepClockRead)?(|Shifty[1:0]) : 1'b0;            //or the last two bits togeather

always @(negedge SysGen_pci_clk)                                            //This code manages the Step Clock timer
begin
     if (SysGenStepClockWrite) begin
          Shifty[16:1] <= DataIn[15:0];                                     //One clock cycle for each bit
			 Shifty[0] <= 0;
     end
else
     Shifty[16:0] <= {1'b0,Shifty[16:1]};                                   //Shifting is way faster that counting
end

//Step clock - before buffering
assign SysGenStep = (SysGen_pci_clk_nobuf) && (Shifty[0]);

endmodule